﻿using System;
using System.Security.Cryptography.X509Certificates;
using Fleck;

namespace Yb
{
    public class websocket
    {
        private static WebSocketServer wsServer = null;
        private static WebSocketServer wssServer = null;
        private static int currentWsPort = 13526;   // 默认 ws 端口
        private static int currentWssPort = 13527;  // 默认 wss 端口（仅当启用 wss 时有效）
        private static string pfxPath = null;
        private static string pfxPassword = null;
        public static event Action<string> OnBgen;
        public static event Action<string> OnStop;
        public static event Action<string> OnError;

        public static Action<string, IWebSocketConnection> Run;

        // ========== 原有 Init 方法（保持兼容） ==========

        public static YbMessage Init()
        {
            return Restart(currentWsPort, currentWssPort, pfxPath, pfxPassword);
        }

        public static YbMessage Init(int port)
        {
            return Restart(port, currentWssPort, pfxPath, pfxPassword);
        }

        public static YbMessage Init(int port,int wssprot, string pfxFilePath, string password)
        {
            return Restart(port, wssprot, pfxFilePath, password);
        }

        // ========== 新增：端口设置方法 ==========

        /// <summary>
        /// 设置 ws 端口，并重启服务（保留 wss 配置）
        /// </summary>
        public static YbMessage SetWsPort(int wsPort)
        {
            if (wsPort <= 0 || wsPort > 65535)
                return new YbMessage(-1, $"❌ 无效 ws 端口: {wsPort}，必须在 1~65535 范围内");

            return Restart(wsPort, wsPort + 1, pfxPath, pfxPassword);
        }

        /// <summary>
        /// 设置 wss 端口，并重启服务（保留 ws 配置）
        /// </summary>
        public static YbMessage SetWssPort(int wssPort)
        {
            if (wssPort <= 0 || wssPort > 65535)
                return new YbMessage(-1, $"❌ 无效 wss 端口: {wssPort}，必须在 1~65535 范围内");

            int wsPort = wssPort - 1;
            if (wsPort < 1)
                return new YbMessage(-1, $"❌ wss 端口 {wssPort} 太小，会导致 ws 端口无效（需 ≥2）");

            return Restart(wsPort, wssPort, pfxPath, pfxPassword);
        }

        /// <summary>
        /// 同时设置 ws 和 wss 端口，并重启服务
        /// </summary>
        public static YbMessage SetPorts(int wsPort, int wssPort)
        {
            if (wsPort <= 0 || wsPort > 65535)
                return new YbMessage(-1, $"❌ 无效 ws 端口: {wsPort}");
            if (wssPort <= 0 || wssPort > 65535)
                return new YbMessage(-1, $"❌ 无效 wss 端口: {wssPort}");
            if (wsPort == wssPort)
                return new YbMessage(-1, "❌ ws 和 wss 端口不能相同");

            return Restart(wsPort, wssPort, pfxPath, pfxPassword);
        }

        // ========== 核心 Restart 方法（支持独立端口） ==========

        private static YbMessage Restart(int wsPort, int wssPort, string pfxFilePath, string password)
        {
            try
            {
                Stop();

                currentWsPort = wsPort;
                currentWssPort = wssPort;
                pfxPath = pfxFilePath;
                pfxPassword = password;

                // 启动 ws
                wsServer = new WebSocketServer($"ws://0.0.0.0:{currentWsPort}");
                wsServer.Start(socket =>
                {
                    SetupSocketEvents(socket);
                });
                OnBgen?.Invoke($"WebSocket (ws) 服务已在端口 {currentWsPort} 启动");
                // 启动 wss（如果提供了证书）
                if (!string.IsNullOrEmpty(pfxPath))
                {
                    if (!System.IO.File.Exists(pfxPath))
                    {
                        return new YbMessage(-1, $"❌ 证书文件不存在: {pfxPath}");
                    }

                    try
                    {
                        var cert = new X509Certificate2(pfxPath, pfxPassword, X509KeyStorageFlags.MachineKeySet);
                        wssServer = new WebSocketServer($"wss://0.0.0.0:{currentWssPort}");
                        wssServer.Certificate = cert;
                        wssServer.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls13;
                        wssServer.Start(socket =>
                        {
                            SetupSocketEvents(socket);
                        });
                        OnBgen?.Invoke($"WebSocket (wss) 服务已在端口 {currentWssPort} 启动");
                    }
                    catch (Exception certEx)
                    {
                        return new YbMessage(-1, $"❌ 加载证书失败: {certEx.Message}");
                    }
                }

                string msg = pfxPath != null
                    ? $"✅ WebSocket 服务已启动: ws://{currentWsPort}, wss://{currentWssPort}"
                    : $"✅ WebSocket (ws) 服务已在端口 {currentWsPort} 启动";
                return new YbMessage(0, msg);
            }
            catch (Exception ex)
            {
                wsServer = null;
                wssServer = null;
                OnError?.Invoke($"❌ 启动 WebSocket 服务失败: {ex.Message}");
                return new YbMessage(-1, $"❌ 启动 WebSocket 服务失败: {ex.Message}");
            }
        }

        // ========== 事件配置（复用） ==========

        private static void SetupSocketEvents(IWebSocketConnection socket)
        {
            socket.OnOpen = () =>
            {
                string id = socket.ConnectionInfo?.Id.ToString() ?? "unknown";
                string origin = socket.ConnectionInfo?.Origin ?? "unknown";
                Console.WriteLine($"✅ WebSocket 连接已建立: {id} ({origin})");
            };

            socket.OnClose = () =>
            {
                string id = socket.ConnectionInfo?.Id.ToString() ?? "unknown";
                Console.WriteLine($"🔌 WebSocket 连接已关闭: {id}");
            };

            socket.OnMessage = message =>
            {
                try
                {
                    Console.WriteLine($"📩 收到消息: {message}");
                    Run?.Invoke(message, socket);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"⚠️ 消息处理异常: {ex.Message}");
                    try { socket.Close(); } catch { }
                }
            };

            socket.OnError = exception =>
            {
                string id = socket.ConnectionInfo?.Id.ToString() ?? "unknown";
                Console.WriteLine($"🔥 WebSocket 错误 [{id}]: {exception.Message}");
                try { socket.Close(); } catch { }
            };
        }

        // ========== 停止服务 ==========

        public static void Stop()
        {
            try
            {
                wsServer?.Dispose();
                wssServer?.Dispose();
                wsServer = null;
                wssServer = null;
                Console.WriteLine("🛑 WebSocket 服务已停止");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"⚠️ 停止 WebSocket 服务时出错: {ex.Message}");
            }
        }

        // ========== 获取当前端口 ==========

        public static string GetCurrentPorts()
        {
            if (wsServer == null && wssServer == null)
                return "-1";

            if (wssServer == null)
                return currentWsPort.ToString();

            return $"{currentWsPort} (ws), {currentWssPort} (wss)";
        }
    }
}